using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public delegate void MessageClick(params object[] value);

public enum MessageButtonType
{
    OK,
    OKANDCALCEL,
}


public static class EX
{
    public static int DisableLayer = 20;
    public static int UILayer = 5;

    //获取文字在text暂用的长度
    public static int CalculateLengthOfText(this MonoBehaviour mono, string message, Text text)
    {
        Font font = text.font;
        font.RequestCharactersInTexture(message, text.fontSize, text.fontStyle);
        CharacterInfo characterInfo = new CharacterInfo();
        char[] array = message.ToCharArray();
        int text_w = 0;

        foreach (char c in array)
        {
            font.GetCharacterInfo(c, out characterInfo, text.fontSize);
            text_w += characterInfo.advance;
        }
        return text_w;
    }

    /// <summary>
    /// 自动换行处理
    /// </summary>
    /// <param name="mono">扩展类</param>
    /// <param name="value">原生内容</param>
    /// <param name="text">需要换行的控件</param>
    /// <param name="width">行宽最大值多少换行 注意:并非精确 会大于或者小雨 一个字符的占位宽度</param>
    /// <returns></returns>
    public static string StringNewLine(this MonoBehaviour mono, string value, Text text, float width)
    {
        string message = string.Empty;
        List<string> msg_list = new List<string>();
        foreach (var item in value)
        {
            if (message == string.Empty) message = item.ToString();
            else
            {
                if (mono.CalculateLengthOfText(message, text) >= width)
                {
                    msg_list.Add(message);
                    message = item.ToString();
                }
                else message += item.ToString();
            }
        }
        if (mono.CalculateLengthOfText(message, text) < width) msg_list.Add(message);
        message = string.Empty;
        foreach (var item in msg_list)
        {
            if (message == string.Empty) message = item;
            else message += $"\r\n{item}";
        }
        return message;
    }

    //创建预制 以父节点发起
    public static T CreatePrefab<T>(this Transform parent,string path, bool active = true)
    {
        GameObject newobj = GameObject.Instantiate(Resources.Load(path), parent) as GameObject;
        newobj.transform.SetParent(parent, false);
        newobj.transform.localPosition = Vector3.zero;
        newobj.SetActive(active);

        T c = newobj.GetComponent<T>();
        if (c == null)
        {
            newobj.AddComponent(typeof(T));
            c = newobj.GetComponent<T>();
        }
        return c;
    }

    public static void RemoveAllChild(this ScrollRect sr)
    {
        for (int i = 0; i < sr.content.childCount; i++)
        {
            GameObject.Destroy(sr.content.GetChild(i).gameObject);
        }
    }

    public static GameObject showLoading(this MonoBehaviour mono) 
    {
        Transform maxOrder = GetMaxOrderTf();
        GameObject newObj = GameObject.Instantiate(Resources.Load<GameObject>("UIPrefab/UIEffects/LoadingPanel"), maxOrder) as GameObject;
        newObj.transform.SetParent(maxOrder, false);
        newObj.transform.SetAsLastSibling();
        return newObj;
    }

    public static void DisableObj(this MonoBehaviour mono,GameObject _obj) 
    {
        _obj.layer = DisableLayer;
    }

    public static void DisPlayObj(this MonoBehaviour mono, GameObject _obj) 
    {
        _obj.layer = UILayer;
    }

    public static GameObject ShowMessageBox(this MonoBehaviour mono, string message,string _okText,string _cancelText, MessageButtonType type = MessageButtonType.OKANDCALCEL, MessageClick okClick = null, MessageClick cancelClick = null)
    {
        Transform maxOrder = GetMaxOrderTf();
        GameObject newObj = GameObject.Instantiate(Resources.Load<GameObject>("MessageBox/MessageBox"), maxOrder) as GameObject;
        MessageBox mb = newObj.AddComponent<MessageBox>();
        if (string.IsNullOrEmpty(_cancelText) || string.IsNullOrWhiteSpace(_cancelText))
            _cancelText = "取消";
        mb.SetData(message, _okText,_cancelText, type, okClick, cancelClick);
        newObj.transform.SetParent(maxOrder, false);
        newObj.transform.SetAsLastSibling();
        return newObj;
    }
    

    public static GameObject ShowPromotBox(this MonoBehaviour mono, string message, float delTime = 2.5f)
    {
        Transform maxOrder = GetMaxOrderTf();
        GameObject newObj = GameObject.Instantiate(Resources.Load<GameObject>("MessageBox/PromptBox"), maxOrder) as GameObject;
        PromptBox pb = newObj.AddComponent<PromptBox>();
        pb.SetValue(message, delTime);
        newObj.transform.SetParent(maxOrder, false);
        newObj.transform.SetAsLastSibling();
        return newObj;
    }

    // 获取两个节点之间的距离
    public static int getDistanceVec(this MonoBehaviour mono, Vector2 a, Vector2 b)
    {
        int cntX = Mathf.Abs((int)(a.x - b.x));
        int cntY = Mathf.Abs((int)(a.y - b.y));
        // 判断到底是那个轴相差的距离更远
        if (cntX > cntY)
        {
            return 14 * cntY + 10 * (cntX - cntY);
        }
        else
        {
            return 14 * cntX + 10 * (cntY - cntX);
        }
    }

    public static T FindComponent<T>(this Component mono, string path = "")
    {
        if (path.Equals(string.Empty)) return mono.gameObject.GetComponent<T>();
        T v = mono.transform.Find(path).GetComponent<T>();
        return v;
    }

    public static GameObject FindComponent(this Component mono, string path)
    {
        return mono.transform.Find(path).gameObject;
    }

    //public static T AddComponent<T>(this Component mono)
    //{
    //    if (mono.gameObject.GetComponent<T>() == null)  mono.gameObject.AddComponent(typeof(T));
    //    return mono.gameObject.GetComponent<T>();
    //}

    public static T InstantiateWnd<T>(this MonoBehaviour mono, string path)
    {
        Transform maxOrder = GetMaxOrderTf();
        GameObject newObj = GameObject.Instantiate(Resources.Load(path), maxOrder) as GameObject;
        Component c = newObj.GetComponent(typeof(T));
        if(c == null) newObj.AddComponent(typeof(T));
        newObj.SetActive(false);
        newObj.transform.SetParent(maxOrder, false);
        newObj.transform.SetAsLastSibling();

        return newObj.GetComponent<T>();
    }

    //public static Transform GetMaxOrderCanvas(this MonoBehaviour mono)
    //{
    //    return GetMaxOrderTf();
    //}

    private static Transform GetMaxOrderTf()
    {
        Canvas[] tmpCanvas = GameObject.FindObjectsOfType<Canvas>();
        Canvas maxOrder = tmpCanvas[0];
        foreach (var item in tmpCanvas) if (item.sortingOrder > maxOrder.sortingOrder) maxOrder = item;
        return maxOrder.transform;
    }


    public static Transform GetMaxOrderTransform(this MonoBehaviour mono)
    {
        return GetMaxOrderTf();
    }

    //  设置位置信息
    public static void SetObjScreenPos(this MonoBehaviour mono,GameObject _parent, Transform go)
    {
        go.SetParent(_parent.transform);
        go.localPosition = Vector3.zero;
        go.localScale = Vector3.one;
        go.localEulerAngles = Vector3.zero;
    }
}


